package com.jdy.utils;

import java.util.function.Supplier;

/**
 * Spring 框架学习
 * <p>
 * Description: spring-mvc
 * <p>
 * Created by 49897 on 2020/3/30 1:13
 */
public class Assert {

    public static <T> T notNull(T object, String message) {
        if (object == null) {
            throw new IllegalArgumentException(message);
        }
        return object;
    }

    public static void notEmpty(Object[] array, String message) {
        if (ObjectUtils.isEmpty(array)) {
            throw new IllegalArgumentException(message);
        }
    }

    public static void hasText(String text, Supplier<String> messageSupplier) {
        if (StringUtils.isBlack(text))
            throw new IllegalArgumentException(nullSafeGet(messageSupplier));
    }

    public static void hasText(String text, String message) {
        if (StringUtils.isBlack(text))
            throw new IllegalArgumentException(message);
    }

    private static String nullSafeGet(Supplier<String> supplier) {
        return supplier == null ? null : supplier.get();
    }

    public static void isTrue(boolean expression, Supplier<String> messageSupplier) {
        if (!expression)
            throw new IllegalArgumentException(nullSafeGet(messageSupplier));
    }

    public static void isTrue(boolean expression, String message) {
        if (!expression) {
            throw new IllegalArgumentException(message);
        }
    }

    public static void hasLength(String text, String message) {
        if (StringUtils.isEmpty(text))
            throw new IllegalArgumentException(message);
    }

    public static void isInstanceOf(Class<?> type, Object object, String message) {
        notNull(type, "Type to check against must not be null");
        if (!type.isInstance(object)) {
            instanceCheckFailed(type, object, message);
        }
    }

    private static void instanceCheckFailed(Class<?> type, Object object, String message) {
        String className = (object == null ? "null" : object.getClass().getName());
        String result = "";
        boolean defaultMessage = true;
        if (StringUtils.isNotEmpty(message)) {
            if (endsWithSeparator(message)) {
                result = message + " ";
            } else {
                result = messageWithTypeName(message, className);
                defaultMessage = false;
            }
        }
        if (defaultMessage) {
            result = result + ("Object of class [" + className + "] must be an instance of " + type);
        }

        throw new IllegalArgumentException(result);
    }

    private static String messageWithTypeName(String message, String typeName) {
        return message + (message.endsWith(" ") ? "" : ": ") + typeName;
    }

    private static boolean endsWithSeparator(String message) {
        return message.endsWith(":") || message.endsWith(";") || message.endsWith(",") || message.endsWith(".");
    }

    private static String messageWithTypeName(String msg, Object typeName) {
        return msg + (msg.endsWith(" ") ? "" : ": ") + typeName;
    }


    public static void isAssignable(Class<?> superType, Class<?> subType) {
        isAssignable(superType, subType, "");
    }

    public static void isAssignable(Class<?> superType, Class<?> subType, String message) {
        notNull(superType, "Super type to check against must not be null");
        if (subType == null || !superType.isAssignableFrom(subType)) {
            assignableCheckFailed(superType, subType, message);
        }
    }

    private static void assignableCheckFailed(Class<?> superType, Class<?> subType, String msg) {
        String result = "";
        boolean defaultMessage = true;
        if (StringUtils.isNotBlack(msg)) {
            if (endsWithSeparator(msg)) {
                result = msg + " ";
            } else {
                result = messageWithTypeName(msg, subType);
                defaultMessage = false;
            }
        }

        if (defaultMessage) {
            result = result + (subType + " is not assignable to " + superType);
        }
        throw new IllegalArgumentException(result);
    }


}
